#!/usr/bin/perl -w

use strict;


# OBRIM EL FITXER FASTA DE LA SEQUENCIA

my $entrada;

$entrada = $ARGV[0];  #$ARGV[0] ES REFEREIX A LA SEQ EN FORMAT FASTA QUE LI DONEM

if (!open(ENTRADA,"< $entrada")) {
  print "impossible obrir $entrada\n";
  exit(1);
}


# ENS SALTEM LA PRIMERA LINIA DE L'IDENTIFICADOR DE LA SEQUENCIA FASTA

my $identificador = <ENTRADA>;       # LLEGEIX LA PRIMERA LINIA
my @sequencia = <ENTRADA>;           # LLEGIEX LA SEQUENCIA
my $seq = "";                        # HI POSAREM TOTA LA SEQUENCIA SEGUIDA
                                     # ENGANXANT LES POSICIONS DEL VECTOR 
                                     # @sequencia

close(ENTRADA);

#AGAFEM LA SEQUENCIA I LI TREIEM ELS \n I LA POSEM TOTA EN UNA VARIABLE ($seq)

my $n=0;

while ($n < scalar(@sequencia)) {

  chomp($sequencia[$n]);
  $seq = $seq . $sequencia[$n];
  $n = $n + 1;
}


# POSEM LA SEQUENCIA EN MAJUSCULES

my $seq1;

$seq1 = uc($seq);


# INICIALITZEM LES VARIABLES A ON EMMAGATZAMEM LES SEQUENCIES AMB ELS 6 MARCS DE LECTURA

my $seqtr;
my $seq2;
my $seq3;

my $rev1;
my $rev2;
my $rev3;


# FEM LA CADENA COMPLEMENTARIA I LA POSEM 5' 3'

$seqtr = $seq1;
$seqtr =~ tr/ACGT/TGCA/;
$rev1= reverse($seqtr);

# FEM ELS SIS MARCS DE LECTURA (LES DUES SEQ QUE FALTEN LES TENIM A $seq1 I Srev1)

$seq2 = substr($seq1,1);
$seq3 = substr($seq1,2);
$rev2 = substr($rev1,1);
$rev3 = substr($rev1,2);

# OBRIM EL FITXER DE SORTIDA 

my $sortida;

$sortida = $ARGV[1];  #$ARGV[1] ES REFEREIX A L'ARXIU DE SORTIDA QUE LI DONEM

# GUARDEM EL NUMERO MINIM DE AA DE LA PROT

my $tall;

$tall = $ARGV[2];   #$ARGV[2] ES REFEREIX AL NUMERO DE TALL DE PROT QUE LI DONEM

################################################
################################################   SEQ1
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ


my $resultat;

my $inici = '';
my $inicirev = "";

$resultat = met(atg($seq1));


# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,"> $sortida");

my $i = 0;
my $j = 0;
my @seq_aa;
my @com_fin;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inici);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura1_fwd_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n"; 

	$j =$j + 1;
    }

    $i = $i + 1;
}

close(SEQUENCIES);

################################################
################################################   SEQ2
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ

$resultat = '';

$inici = '';

$resultat = met(atg($seq2));


# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,">> $sortida");

$i = 0;
$j = 0;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inici);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura2_fwd_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n"; 
	
	$j =$j + 1;
    }

    $i = $i + 1;
}

close(SEQUENCIES);

################################################
################################################   SEQ3
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ

$resultat = '';

$inici = '';

$resultat = met(atg($seq3));


# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,">>  $sortida");

$i = 0;
$j = 0;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inici);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura3_fwd_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n"; 

	$j =$j + 1;
    }

    $i = $i + 1;
}

close(SEQUENCIES);

################################################
################################################   REV1
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ

$resultat = '';

$inicirev = '';

$resultat = met(atg($rev1));


# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,">>  $sortida");

$i = 0;
$j = 0;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inicirev);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura1_rev_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n"; 

	$j =$j + 1;
    }

    $i = $i + 1;
}

close(SEQUENCIES);

################################################
################################################   REV2
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ

$resultat = '';

$inicirev = '';

$resultat = met(atg($rev2));


# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,">>  $sortida");

$i = 0;
$j = 0;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inicirev);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura2_rev_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n";   
	
	$j = $j + 1; 
    }

    $i = $i + 1;
}

close(SEQUENCIES);

################################################
################################################   REV3
################################################
#CRIDEM LES DUES FUNCIONS QUE TRADUEIXEN EL DNA A PROT; A $resultat OBTENIM ELS AA PER EL MARC DE LECTURA 1 ($seq1) 
#A $inici TENIM LES POSICIONS D'INICI I FINAL DE TRADUCCIÓ

$resultat = '';

$inicirev = '';

$resultat = met(atg($rev3));

# CONVERTIM LA SEQ DE PROT EN FORMAT FASTA; TALLEM CADA PROTEINA I LES TENIM EN DIFERENTS POSICIONS DEL VECTOR @seq_aa
# TALLEM LES POSICIONS I LES POSEM EN LES DIFERENTS POSICIONS DEL VECTOR @com_fin
# FEM UN BUCLE I IMPRIMIM LA LINIA DE DESCRIPCIO I LA SEQ DE CADA PROT


open(SEQUENCIES,">>  $sortida");

$i = 0;
$j = 0;

@seq_aa = split(/\*/, $resultat);

@com_fin = split(/\*/, $inicirev);


while ($i < scalar(@seq_aa)){

    if (length($seq_aa[$i]) > $tall){

	print SEQUENCIES ">Prot";
	print SEQUENCIES $j;
	print SEQUENCIES "_pautalectura3_rev_";
	print SEQUENCIES $com_fin[$i], "\n";
	print SEQUENCIES $seq_aa[$i], "\n"; 

	$j = $j + 1; 
    }

    $i = $i + 1;
}

close(SEQUENCIES);

##########################################################################
##########################################################################
##########################################################################
#FUNCIONS:


#FEM UNA FUNCIO QUE BUSCA ATG I STOP: 
#$num conta posicions de nucleotid (
#$i es el contador que abanca posicions
#$z es el marcador que indica l'inici i l'stop (quan es atg $z = 1 i quan trobem l'stop passa a ser 0, mentre $z=1 tenim la proteina)
#$prot es on s'encadena la sequencia proteica
#$longitu es l'allargada del vector
#$final correspon al tercer nucleotid del stop



sub atg {

    my @codons;

    @codons = ($_[0] =~ m/.../g);

    my $i = 0;
    my $z = 0;
    my $prot = "";
    my $longitud = scalar(@codons);
    my $num = 1;
    my $num2 = 1;
    my $final = 0;
    my $finalrev = 0;
    my $num3 = 0;
    while ($i < $longitud){


	if ($codons[$i] eq "ATG" && $z == 0){

	    $z = 1;

            ########GUARDEM LA POSICIO INICIAL DE LES PROT PER A LES SEQ FWD

	    $inici = $inici.$num;

            ########GUARDEM LA POSICIO INICIAL DE LES PROT PER A LES SEQ REV 

	    $num2 = $longitud * 3;
	    $num3 = $num2 - $num;
	    $inicirev = $inicirev.$num3;
	}

	while (($z == 1) && ($i < $longitud)){	

	    $prot = $prot.$codons[$i];

	    if (($codons[$i] eq 'TAA')||($codons[$i] eq 'TAG')||($codons[$i] eq 'TGA')){

		$z = 0;

            ########GUARDEM LA POSICIO FINAL DE LES PROT PER A LES SEQ FWD

	    $inici = $inici.'_';
	    $final = $num + 2;
	    
	    $inici = $inici.$final;
	    $inici = $inici.'*';
	
            ########GUARDEM LA POSICIO FINAL DE LES PROT PER A LES SEQ REV

	    $inicirev = $inicirev.'_';
            $finalrev = $longitud * 3;
	    $finalrev = $finalrev - $final;
            $inicirev = $inicirev.$finalrev;
	    $inicirev = $inicirev.'*';
	    }

	    else {

		$i = $i + 1;

		$num = $num + 3;
            }
	        
	}
	    $i = $i + 1;
	
	$num = $num + 3;
        
    }
    return $prot;
  }




# FUNCIÓ QUE TRADUEIX EL DNA A PROT
#@proteina conte el vector amb la sequencia de nucleotids. Aqui la tallem per codons 
#hash %codi tradueix els codons a aminoacid de tres lletres
#hash %lletra passa el codi de tres lletres a una lletra

sub met {

    my @proteina;

    @proteina = ($_[0] =~ m/.../g);



my %codi=("TTT" => "Phe",
             "TTC" => "Phe",
             "TTA" => "Leu",
             "TTG" => "Leu",
             "CTT" => "Leu",
             "CTC" => "Leu",
             "CTA" => "Leu",
             "CTG" => "Leu",
             "ATT" => "Ile",
             "ATC" => "Ile",
             "ATA" => "Ile",
             "ATG" => "Met",
             "GTT" => "Val",
             "GTC" => "Val",
             "GTA" => "Val",
             "GTG" => "Val",
             "TCT" => "Ser",
             "TCC" => "Ser",
             "TCA" => "Ser",
             "TCG" => "Ser",
             "CCT" => "Pro",
             "CCC" => "Pro",
             "CCA" => "Pro",
             "CCG" => "Pro",
             "ACT" => "Thr",
             "ACC" => "Thr",
             "ACA" => "Thr",
             "ACG" => "Thr",
             "GCT" => "Ala",
             "GCC" => "Ala",
             "GCA" => "Ala",
             "GCG" => "Ala",
             "TAT" => "Tyr",
             "TAC" => "Tyr",
             "TAA" => "Stop",
             "TAG" => "Stop",
             "CAT" => "His",
             "CAC" => "His",
             "CAA" => "Gln",
             "CAG" => "Gln",
             "AAT" => "Asn",
             "AAC" => "Asn",
             "AAA" => "Lys",
             "AAG" => "Lys",
             "GAT" => "Asp",
             "GAC" => "Asp",
             "GAA" => "Glu",
             "GAG" => "Glu",
             "TGT" => "Cys",
             "TGC" => "Cys",
             "TGA" => "Stop",
             "TGG" => "Trp",
             "CGT" => "Arg",
             "CGC" => "Arg",
             "CGA" => "Arg",
             "CGG" => "Arg",
             "AGT" => "Ser",
             "AGC" => "Ser",
             "AGA" => "Arg",
             "AGG" => "Arg",
             "GGT" => "Gly",
             "GGC" => "Gly",
             "GGA" => "Gly",
             "GGG" => "Gly");


my %lletra=("A" => "Ala",
           "R" => "Arg",
           "N" => "Asn",
           "D" => "Asp",
           "C" => "Cys",
           "Q" => "Gln",
           "E" => "Glu",
           "G" => "Gly",
           "H" => "His",
           "I" => "Ile",
           "L" => "Leu",
           "K" => "Lys",
           "M" => "Met",
           "F" => "Phe",
           "P" => "Pro",
           "S" => "Ser",
           "X" => "Ter",
           "T" => "Thr",
           "W" => "Trp",
           "Y" => "Tyr",
           "V" => "Val",
           "*" => "Stop",);


#%lletra2 fem el reverse del hash lletra
#$i conta posicions vector
#$aa encadena els aa de la proteina 



my $i=0;

my $aa = "";

my %lletra2=reverse(%lletra);
   

    while ($i < scalar(@proteina)) {

	$aa = $aa.$lletra2{$codi{$proteina[$i]}};

	$i = $i + 1;
    }

    return $aa;
}


